home *** CD-ROM | disk | FTP | other *** search
/ United Public Domain Gold 4 / United Public Domain Gold 4.iso / fredfish / ff.0316.dms / ff.0316.adf / Life / readin.c < prev    next >
C/C++ Source or Header  |  1990-02-06  |  6KB  |  291 lines

  1. /*
  2.  *   ReadIn() reads in a programmable life generation.
  3.  */
  4. #include "stdio.h"
  5. extern int wmodulo, modulo, vsize ;
  6. #define MAXSIZE 8000L
  7. #define MAXSTACK 20
  8. #define MINX 1
  9. #define MAXX (modulo - 2)
  10. #define MINY 1
  11. #define MAXY (vsize - 2)
  12. static char *arr[26] ;
  13. static short dirs[] = { -1, 0, 0, -1, 1, 0, 0, 1 } ;
  14. static int sp ;
  15. static int xstack[MAXSTACK], ystack[MAXSTACK] ;
  16. static char dirstack[MAXSTACK], onstack[MAXSTACK], ddirstack[MAXSTACK] ;
  17. static int x, y, dir, on, ddir ;
  18. static short *globala ;
  19. readin(a)
  20. short *a ;
  21. {
  22.    int c ;
  23.    char *p ;
  24.    int i ;
  25.    char *prog ;
  26.  
  27.    globala = a ;
  28.    for (i=0; i<26; i++)
  29.       arr[i] = NULL ;
  30.    prog = (char *)AllocMem(MAXSIZE, 0L) ;
  31.    if (prog == NULL) return ;
  32. /*
  33.  *   First, we read the program into memory, stripping comments and
  34.  *   other nonsense characters.  We enclose the whole thing in an
  35.  *   extra pair of parenthesis.
  36.  */
  37.    p = prog ;
  38.    *p++ = '(' ;
  39.    while ((c=getchar())!=EOF) {
  40.       if (c=='<') {
  41.          while ((c=getchar())!=EOF && c!='>') ;
  42.          if (c==EOF || (c=getchar())==EOF) break ;
  43.       }
  44.       if (c >= 'A' && c <= 'Z')
  45.          c += 'a' - 'A' ;
  46.       if ((c >= 'a' && c <= 'z') || c=='+' || c=='-' || c=='(' || c==')' ||
  47.           c=='[' || c==']' || c=='=' || (c >= '0' && c <= '9') || c=='.' ||
  48.           c=='*' || c==',') {
  49.          *p++ = c ;
  50.          if (prog + MAXSIZE - 3 <= p) {
  51.             printf("Out of room in program space.\n") ;
  52.             goto out ;
  53.          }
  54.       }
  55.    }
  56.    *p++ = ')' ;
  57. /*
  58.  *   Now we process the thing.
  59.  */
  60.    x = modulo / 2 ;
  61.    y = vsize / 2 ;
  62.    dir = 2 ;
  63.    ddir = 2 ;
  64.    on = 0 ;
  65.    sp = MAXSTACK - 1 ;
  66.    process(prog) ;
  67. out:   
  68.    FreeMem(prog, MAXSIZE) ;
  69. }
  70. /*
  71.  *   This routine actually does the processing.
  72.  */
  73. process(where)
  74. char *where ;
  75. {
  76.    long param ;
  77.  
  78.    if (*where != '(')
  79.       printf("Expected open paren!\n") ;
  80.    where++ ;
  81.    while (*where != ')' && *where != 0) {
  82.       if (*where >= '0' && *where <= '9') {
  83.          param = 0 ;
  84.          while (*where >= '0' && *where <= '9')
  85.             param = 10 * param + *where++ - '0' ;
  86.       } else
  87.          param = 1 ;
  88.       if (*where == '(') {
  89.          while (param > 0) {
  90.             process(where) ;
  91.             param-- ;
  92.          }
  93.          skip(&where) ;
  94.       } else if (*where=='=') {
  95.          where++ ;
  96.          if (*where < 'a' || *where > 'z') {
  97.             printf("Can't define that char!\n") ;
  98.             *where = 'a' ;
  99.          }
  100.          if (where[1] != '(')
  101.             printf("Expected definition to start with (!\n") ;
  102.          arr[*where-'a'] = where + 1 ;
  103.          where++ ;
  104.          skip(&where) ;
  105.       } else
  106.          doone(*where++, param) ;
  107.    }
  108. }
  109. /*
  110.  *   This routine handles a single character.
  111.  */
  112. doone(c, param)
  113. char c ;
  114. long param ;
  115. {
  116.    switch(c) {
  117. case '[' :
  118.       if (sp < 0) {
  119.          printf("Stack overflow!\n") ;
  120.          sp = 0 ;
  121.       }
  122.       xstack[sp] = x ;
  123.       ystack[sp] = y ;
  124.       dirstack[sp] = dir ;
  125.       ddirstack[sp] = ddir ;
  126.       onstack[sp] = on ;
  127.       sp-- ;
  128.       goto setpoint ;
  129. case ']' :
  130.       sp++ ;
  131.       if (sp >= MAXSTACK) {
  132.          printf("Stack underflow!\n") ;
  133.          sp = MAXSTACK-1 ;
  134.       }
  135.       x = xstack[sp] ;
  136.       y = ystack[sp] ;
  137.       dir = dirstack[sp] ;
  138.       ddir = ddirstack[sp] ;
  139.       on = onstack[sp] ;
  140.       goto setpoint ;
  141. case 'x' :
  142.       x = param ;
  143.       if (x < MINX)
  144.          x = MINX ;
  145.       if (x > MAXX)
  146.          x = MAXX ;
  147.       goto setpoint ;
  148. case 'y' :
  149.       y = param ;
  150.       if (y < MINY)
  151.          x = MINY ;
  152.       if (y > MAXY)
  153.          y = MAXY ;
  154.       goto setpoint ;
  155. case '.' :
  156.       while (param > 0) {
  157.          x += dirs[dir] ;
  158.          y += dirs[dir+1] ;
  159.          if (x < MINX)
  160.             x = MAXX ;
  161.          if (x > MAXX)
  162.             x = MINX ;
  163.          if (y < MINY)
  164.             y = MAXY ;
  165.          if (y > MAXY)
  166.             y = MINY ;
  167.          param-- ;
  168.       }
  169.       break ;
  170. case 'f' :
  171.       while (param > 0) {
  172.          x += dirs[dir] ;
  173.          y += dirs[dir+1] ;
  174.          if (x < MINX)
  175.             x = MAXX ;
  176.          if (x > MAXX)
  177.             x = MINX ;
  178.          if (y < MINY)
  179.             y = MAXY ;
  180.          if (y > MAXY)
  181.             y = MINY ;
  182.          if (on)
  183.             set(x, y) ;
  184.          param-- ;
  185.       }
  186.       break ;
  187. case '*' :
  188.       while (param > 0) {
  189.          x += dirs[dir] ;
  190.          y += dirs[dir+1] ;
  191.          if (x < MINX)
  192.             x = MAXX ;
  193.          if (x > MAXX)
  194.             x = MINX ;
  195.          if (y < MINY)
  196.             y = MAXY ;
  197.          if (y > MAXY)
  198.             y = MINY ;
  199.          set(x, y) ;
  200.          param-- ;
  201.       }
  202.       break ;
  203. case ',' :
  204.       while (param > 0) {
  205.          x += dirs[(dir + ddir) & 6] ;
  206.          y += dirs[((dir + ddir) & 6) + 1] ;
  207.          if (x < MINX)
  208.             x = MAXX ;
  209.          if (x > MAXX)
  210.             x = MINX ;
  211.          if (y < MINY)
  212.             y = MAXY ;
  213.          if (y > MAXY)
  214.             y = MINY ;
  215.          param-- ;
  216.       }
  217.       break ;
  218. case 'l' :
  219.       dir = (dir - ddir) & 6 ;
  220.       break ;
  221. case 'r' :
  222.       dir = (dir + ddir) & 6 ;
  223.       break ;
  224. case 'b' :
  225.       dir = (dir + 4) & 6 ;
  226.       break ;
  227. case 'u' :
  228.       on = 0 ;
  229.       break ;
  230. case 'd' :
  231.       on = 1 ;
  232.       goto setpoint ;
  233. case '+' :
  234.       ddir = 2 ;
  235.       break ;
  236. case '-' :
  237.       ddir = - ddir ;
  238.       break ;
  239. default:
  240.       if (c < 'a' || c > 'z' || 
  241.             arr[c - 'a']==NULL) {
  242.          printf("Bogus! %d\n", c) ;
  243.       } else {
  244.          while (param > 0) {
  245.             process(arr[c-'a']) ;
  246.             param-- ;
  247.          }
  248.       }
  249.       break ;
  250. setpoint:
  251.       if (on)
  252.          set(x, y) ;
  253.       break ;
  254.    }
  255. }
  256. /*
  257.  *   This routine skips to the end of a routine by counting
  258.  *   parenthesis, if any.
  259.  */
  260. skip(where)
  261. char **where ;
  262. {
  263.    char *p = *where ;
  264.    int parencount = 1 ;
  265.  
  266.    if (*p++ == '(') {
  267.       while (parencount > 0) {
  268.          if (*p == '(')
  269.             parencount++ ;
  270.          else if (*p == ')')
  271.             parencount-- ;
  272.          else if (*p == 0) {
  273.             *where = p ;
  274.             break ;
  275.          }
  276.          p++ ;
  277.       }
  278.    }
  279.    *where = p ;
  280. }
  281. /*
  282.  *   This routine turns on a pixel.
  283.  */
  284. static bits[16] = { 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200,
  285.    0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 } ;
  286. set(x, y)
  287. int x, y ;
  288. {
  289.    globala[y * wmodulo + (x >> 4)] |= bits[x & 15] ;
  290. }
  291.